home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / submit / rd_rfchdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  24.5 KB  |  1,137 lines

  1. /* rd_rfchdr.c: parse 822 headers */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/submit/RCS/rd_rfchdr.c,v 6.0 1991/12/18 20:28:02 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/submit/RCS/rd_rfchdr.c,v 6.0 1991/12/18 20:28:02 jpo Rel $
  9.  *
  10.  * $Log: rd_rfchdr.c,v $
  11.  * Revision 6.0  1991/12/18  20:28:02  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "head.h"
  19. #include <isode/cmd_srch.h>
  20. #include "q.h"
  21. #include "tb_q.h"
  22. #include "or.h"
  23. #include "ap.h"
  24. #include "x400_ub.h"
  25.  
  26. extern void err_abrt();
  27. extern char *compress();
  28. static int hdr_parse ();
  29. static int hdr_type (), fillin_DomId();
  30. static void hdr_rcv ();
  31. static void hdr_via ();
  32. static void hdr_check ();
  33. static void hdr_subject ();
  34. static void hdr_date ();
  35. static void hdr_msgid ();
  36. static void hdr_remcomm ();
  37. static void do_correlators ();
  38. static int getline ();
  39. static int got_x400_mts_id = FALSE;
  40. static int ua_id_set_by_x400 = FALSE;
  41. static void     hdr_x400_content_id(),
  42.         hdr_priority(),
  43.         hdr_x400_mts_id(),
  44.         hdr_dl_history(),
  45.         hdr_conversion(),
  46.         hdr_convert_with_loss(),
  47.         hdr_x400_received(),
  48.         hdr_def_deliv(),
  49.         hdr_latest_time(),
  50.         hdr_orig_eit (),
  51.         hdr_prohibition (),
  52.         hdr_gen_del_report(),
  53.         hdr_prev_non_del_report();
  54.  
  55. static char cor_to[BUFSIZ], *cor_subject = NULLCP,
  56.     *cor_date = NULLCP, *cor_mid = NULLCP;
  57. static int cor_to_len;
  58.  
  59. #define ub_content_id_length    16
  60. #define ub_content_correlator_length 512
  61.  
  62. /* -- basic states for the state machine -- */
  63. #define HDV_EOH            0
  64. #define HDV_NEW            1
  65. #define HDV_MORE        2
  66.  
  67. /* -- munge the header lines of the message -- */
  68. #define HDR_FROM        1
  69. #define HDR_SENDER        2
  70. #define HDR_REPLYTO        3
  71. #define HDR_RECEIVED        4
  72. #define HDR_VIA            5
  73. #define HDR_DATE        6
  74. #define HDR_MESSAGEID        7
  75. #define HDR_SUBJECT        8
  76.  
  77. /* rfc 1138 fields */
  78. /* mts */
  79. #define HDR_X400_MTS_ID        9
  80. #define    HDR_ORIG_EIT        10
  81. #define HDR_CONTENT_IDENTIFIER    11
  82. #define HDR_PRIORITY        12
  83. #define HDR_DL_HISTORY        13
  84. #define HDR_CONVERSION        18
  85. #define HDR_CONVERT_WITH_LOSS    14
  86. /* mta */
  87. #define HDR_X400_RECEIVED    15
  88. #define HDR_DEF_DELIV        16
  89. #define HDR_LAST_DELIV        17
  90.  
  91. /* needed for content correlator */
  92. #define HDR_TO            19
  93.  
  94. /* appendix H of rfc 1148 bis */
  95. #define HDR_GEN_DEL_REPORT    20
  96. #define HDR_PREV_NON_DEL_REPORT    21
  97. #define HDR_ALT_RECIP        22
  98. #define HDR_DISCLOSE_RECIPS    23
  99. #define HDR_CONT_RETURN        24
  100.  
  101. /* appendix B of rfc 1148 bis */
  102. #define HDR_ACK_TO        25
  103. /* greybook specific so done in greybook */
  104.  
  105. static    CMD_TABLE  htbl_rfc [] = {
  106.     "from",            HDR_FROM,
  107.     "sender",        HDR_SENDER,
  108.     "reply-to",        HDR_REPLYTO,
  109.     "received",        HDR_RECEIVED,
  110.     "via",            HDR_VIA,
  111.     "date",            HDR_DATE,
  112.     "message-id",        HDR_MESSAGEID,
  113.     "subject",        HDR_SUBJECT,
  114. /* rfc 1138 */
  115.     "x400-mts-identifier",    HDR_X400_MTS_ID,
  116.     "original-encoded-information-types",    HDR_ORIG_EIT,
  117.     "content-identifier",    HDR_CONTENT_IDENTIFIER,
  118.     "priority",        HDR_PRIORITY,
  119.     "dl-expansion-history",    HDR_DL_HISTORY,
  120.     "conversion",        HDR_CONVERSION,
  121.     "conversion-with-loss",    HDR_CONVERT_WITH_LOSS,
  122.     "x400-received",    HDR_X400_RECEIVED,
  123.     "deferred-delivery",    HDR_DEF_DELIV,
  124.     "latest-delivery-time",    HDR_LAST_DELIV,
  125.     "to",            HDR_TO,
  126.     "generate-delivery-report",    HDR_GEN_DEL_REPORT,
  127.     "prevent-nondelivery-report",    HDR_PREV_NON_DEL_REPORT,
  128.     "alternate-recipient",    HDR_ALT_RECIP,
  129.     "disclose-recipients",    HDR_DISCLOSE_RECIPS,
  130.     "content-return",    HDR_CONT_RETURN,
  131.     0,            0
  132.     };
  133.  
  134.  
  135. /* -- statics -- */
  136. static    FILE            *hdr_fp;
  137. static    int            from_count,
  138.                 trace_count,
  139.                 date_count,
  140.                 hdr_prefix,
  141.                 redistributed_mail,
  142.                 sender_count,
  143.                 x400_receiveds;
  144. static Trace            *date_trace;
  145.  
  146. /* -- externals -- */
  147. extern    Q_struct        Qstruct;
  148. extern CHAN *ch_inbound;
  149. extern char *loc_dom_mta;
  150.  
  151.  
  152.  
  153.  
  154. /* ---------------------  Begin     Routines  -------------------------------- */
  155.  
  156.  
  157.  
  158.  
  159. void rd_rfchdr (file)  /* -- basic processing of incoming header lines -- */
  160. char            *file;
  161. {
  162.     char    *bp,
  163.         *name = NULLCP,       /* hdr content location */
  164.         *contents = NULLCP;
  165.     int    retval = NOTOK,
  166.         type;
  167.  
  168.  
  169.     PP_DBG (("submit/rd_rfchdr (%s)", file));
  170.  
  171.     sender_count        = 0;
  172.     from_count        = 0;
  173.     trace_count        = 0;
  174.     date_count        = 0;
  175.     redistributed_mail    = FALSE;
  176.     ua_id_set_by_x400     = FALSE;
  177.     got_x400_mts_id        = FALSE;
  178.     x400_receiveds        = 0;
  179.     date_trace        = (Trace *) NULL;
  180.     cor_to[0] = '\0';
  181.     cor_to_len = sizeof cor_to;
  182.     cor_mid = NULLCP;
  183.     cor_date = NULLCP;
  184.     cor_subject = NULLCP;
  185.  
  186.     if ((hdr_fp = fopen (file, "r")) == NULL)
  187.         err_abrt (RP_FIO,
  188.             "Unable to open '%s'", file);
  189.  
  190.  
  191.     while (getline (&bp, hdr_fp) == OK) {
  192.         hdr_prefix = FALSE;
  193.  
  194.         switch (retval = hdr_parse (bp, &name, &contents)) {
  195.             case HDV_MORE:
  196.             continue;
  197.             case HDV_NEW:
  198.             if ((type = hdr_type (name)) > 0)
  199.                 hdr_check (type, contents);
  200.             continue;
  201.             case HDV_EOH:
  202.             break;
  203.             case NOTOK:
  204.             err_abrt(RP_USER, "Unable to parse '%s' as key:field", bp);
  205.             break;
  206.         }
  207.         break;
  208.     }
  209.  
  210.     (void) fclose (hdr_fp);
  211.  
  212.     do_correlators();
  213.  
  214.     if (retval != HDV_EOH)
  215.         PP_DBG (("submit/rd_rfchdr/retval (%d) != hdr_eoh", retval));
  216.  
  217.     if (ch_inbound -> ch_access == CH_MTS &&
  218.         sender_count == 0 && from_count == 0)
  219.         err_abrt (RP_USER, "No sender given");
  220.     if (ch_inbound -> ch_strict_mode == CH_STRICT_CHECK) {
  221.         if (date_count == 0)
  222.             err_abrt (RP_USER, "No date field given");
  223.         else if (date_count != 1)
  224.             err_abrt (RP_USER, "Too many date fields (%d)",
  225.                   date_count);
  226.     }
  227. }
  228.  
  229. /* ---------------------  Static  Routines  ------------------------------- */
  230.  
  231. static int hdr_parse (txt, name, contents)    /* -- parse one header line -- */
  232. register char        *txt;          /* -- a line of header text -- */
  233. char            **name;          /* -- location of field's name -- */
  234. char            **contents;    /* -- location of field's contents -- */
  235. {
  236.     char        linetype;
  237.  
  238.  
  239.     PP_DBG (("submit/hdr_parse (%s)", txt));
  240.  
  241.  
  242.     if (isspace (*txt)) {
  243.         /* -- continuation text -- */
  244.         if (*txt == '\n' || *txt == '\0')
  245.             return (HDV_EOH);
  246.         linetype = HDV_MORE;
  247.     }
  248.     else  {
  249.         linetype = HDV_NEW;
  250.  
  251.         *name = txt;
  252.         while (*txt && *txt != ':')
  253.             txt ++;
  254.         if (*txt == '\0' || *txt == '\n')
  255.             return NOTOK;
  256.         *txt ++ = '\0';
  257.  
  258.         (void) compress (*name, *name);
  259.     }
  260.  
  261.  
  262.     *contents = txt;
  263.     (void) compress (*contents, *contents);
  264.  
  265.     return (linetype);
  266. }
  267.  
  268. static int hdr_type (name)    /* -- return the type of the component  -- */
  269. char    *name;
  270. {
  271.     PP_DBG (("submit/hdr_type (%s)",name));
  272.  
  273.     if (prefix ("Resent-", name)) {
  274.         name += 7;
  275.         goto doremail;
  276.     }
  277.     if (prefix ("Remailed-", name)) {
  278.         name += 9;
  279.         goto doremail;
  280.     }
  281.     if (prefix ("Redistributed-", name)) {
  282.         name += 14;
  283. doremail:
  284.         hdr_prefix = TRUE;
  285.         if (!redistributed_mail) {
  286.             sender_count = from_count = 0;
  287.             redistributed_mail = TRUE;
  288.         }
  289.     }
  290.  
  291.     return (cmd_srch (name, htbl_rfc));
  292. }
  293.  
  294. static void hdr_check (type, body)
  295. char    *body;
  296. int    type;
  297. {
  298.     AP_ptr    ap;
  299.     int hlen;
  300.  
  301.     PP_DBG (("submit/hdr_check (%d,%s)", type, body));
  302.  
  303.     if (type <= 0)
  304.         return;        /* -- for all unknown types -- */
  305.  
  306.     switch (type) {
  307.         case HDR_SENDER:
  308.         if (redistributed_mail && !hdr_prefix)
  309.             break;
  310.         if ((ap = ap_s2t (body)) == NULLAP)
  311.             err_abrt (RP_USER, "Syntactically invalid address for sender '%s'", body);
  312.         else
  313.             ap_free(ap);
  314.         sender_count++;
  315.         break;
  316.         case HDR_TO:
  317.         if (cor_to[0] != '\0' && cor_to_len > 4) {
  318.             (void) strcat (cor_to, ", ");
  319.             cor_to_len -= 2;
  320.         }
  321.         if ((hlen = strlen (body)) > cor_to_len)
  322.             cor_to_len = 0;
  323.         else {
  324.             (void) strncat (cor_to, body, cor_to_len);
  325.             cor_to_len -= hlen;
  326.         }
  327.         break;
  328.         case HDR_FROM:
  329.         if (redistributed_mail && !hdr_prefix)
  330.             break;
  331.         if ((ap = ap_s2t (body)) == NULLAP)
  332.             err_abrt (RP_USER, "Syntactically invalid address for from field '%s'", body);
  333.         else
  334.             ap_free(ap);
  335.         from_count++;
  336.         break;
  337.         case HDR_REPLYTO:
  338.         if (redistributed_mail && !hdr_prefix)
  339.             break;
  340.         break;
  341.         case HDR_VIA:
  342.         hdr_via (body);
  343.         break;
  344.         case HDR_RECEIVED:
  345.         hdr_rcv (body);
  346.         break;
  347.         case HDR_MESSAGEID:
  348.         hdr_msgid (body);
  349.         break;
  350.         case HDR_DATE:
  351.         if (hdr_prefix == FALSE) {
  352.             hdr_date (body);
  353.             date_count++;
  354.         }
  355.         break;
  356.         case HDR_SUBJECT:
  357.         hdr_subject (body);
  358.         break;
  359.         case HDR_X400_MTS_ID:
  360.         hdr_x400_mts_id (body);
  361.         break;
  362.         case HDR_ORIG_EIT:
  363.         hdr_orig_eit (body);
  364.         break;
  365.         case HDR_CONTENT_IDENTIFIER:
  366.         hdr_x400_content_id (body);
  367.         break;
  368.         case HDR_PRIORITY:
  369.         hdr_priority(body);
  370.         break;
  371.         case HDR_DL_HISTORY:
  372.         hdr_dl_history(body);
  373.         break;
  374.         case HDR_CONVERSION:
  375.         hdr_conversion(body);
  376.         break;
  377.         case HDR_CONVERT_WITH_LOSS:
  378.         hdr_convert_with_loss(body);
  379.         break;
  380.         case HDR_X400_RECEIVED:
  381.         hdr_x400_received (body);
  382.         break;
  383.         case HDR_DEF_DELIV:
  384.         hdr_def_deliv (body);
  385.         break;
  386.         case HDR_LAST_DELIV:
  387.         hdr_latest_time (body);
  388.         break;
  389.         case HDR_GEN_DEL_REPORT:
  390.         hdr_gen_del_report ();
  391.         break;
  392.         case HDR_PREV_NON_DEL_REPORT:
  393.         hdr_prev_non_del_report ();
  394.         break;
  395.         case HDR_ALT_RECIP:
  396.         hdr_prohibition(body, &(Qstruct.alternate_recip_allowed));
  397.         break;
  398.         case HDR_DISCLOSE_RECIPS:
  399.         hdr_prohibition(body, &(Qstruct.disclose_recips));
  400.         break;
  401.         case HDR_CONT_RETURN:
  402.         hdr_prohibition(body, &(Qstruct.content_return_request));
  403.         break;
  404.         default:
  405.         break;
  406.     }            /* -- switch  -- */
  407. }
  408.  
  409. static void hdr_subject (str)
  410. char    *str;
  411. {
  412.     char    buf[BUFSIZ];
  413.  
  414.     if (cor_subject == NULLCP)
  415.         cor_subject = strdup(str);
  416.  
  417.     if (ua_id_set_by_x400 == TRUE)
  418.         return;
  419.     if (Qstruct.ua_id != NULLCP)
  420.         return;
  421.     bzero (buf, sizeof buf);
  422.     if ((int)strlen(str) >= ub_content_id_length) {
  423.         (void) strncat (buf, str, (ub_content_id_length-strlen("...")));
  424.         (void) strcat (buf, "...");
  425.     } else
  426.         (void) strcat (buf, str);
  427.     Qstruct.ua_id = strdup (buf);
  428. }
  429.  
  430. static void hdr_x400_content_id (str)
  431. char    *str;
  432. {
  433.     char    buf[BUFSIZ];
  434.  
  435.     if (Qstruct.ua_id != NULLCP)
  436.         free(Qstruct.ua_id);
  437.     bzero (buf, sizeof buf);
  438.     if ((int)strlen(str) >= ub_content_id_length) {
  439.         (void) strncat (buf, str, (ub_content_id_length-strlen("...")));
  440.         (void) strcat (buf, "...");
  441.     } else
  442.         (void) strncat (buf, str, strlen(str));
  443.     Qstruct.ua_id = strdup (buf);
  444.     ua_id_set_by_x400 = TRUE;
  445. }
  446.  
  447. static void hdr_priority (str)
  448. char    *str;
  449. {
  450.     (void) compress(str, str);
  451.     if (lexequ(str, "normal") == 0)
  452.         Qstruct.priority = PRIO_NORMAL;
  453.     else if (lexequ(str, "urgent") == 0)
  454.         Qstruct.priority = PRIO_URGENT;
  455.     else if (lexequ(str, "non-urgent") == 0
  456.         || lexequ(str, "nonurgent") == 0)
  457.         Qstruct.priority = PRIO_NONURGENT;
  458. }
  459.  
  460. static void hdr_dl_history (str)
  461. char    *str;
  462. {
  463.     register DLHistory    *dlp;
  464.     char *cp;
  465.     int n;
  466.     OR_ptr or;
  467.     UTC utc;
  468.     char buf[BUFSIZ];
  469.  
  470.     if ((cp = index(str, ';')) == NULL) {
  471.         PP_LOG (LLOG_EXCEPTIONS, ("Illegal DLHistory field %s", str));
  472.         return;
  473.     }
  474.     if ((n = cp - str) >= BUFSIZ)
  475.         n = BUFSIZ - 1;
  476.     (void) strncpy (buf, str, n);
  477.     buf[n] = 0;
  478.     if (or_rfc2or_aux (buf, &or, 1) == NOTOK) {
  479.         PP_LOG (LLOG_EXCEPTIONS,
  480.             ("Illegal rfc822 address in DLHistory %s", buf));
  481.         return;
  482.     }
  483.     or_or2std (or, buf, FALSE);
  484.     or_free (or);
  485.     cp ++;
  486.     if (index (cp, ';') == NULL)
  487.         PP_LOG (LLOG_EXCEPTIONS,
  488.             ("DLhistory Missing trailing ';' in %s", str));
  489.     if (rfc2UTC (cp, &utc) == NOTOK) {
  490.         PP_LOG (LLOG_EXCEPTIONS, ("DLhistory: bad time in %s", str));
  491.         return;
  492.     }
  493.     dlp = (DLHistory *)smalloc (sizeof *dlp);
  494.     dlp -> dlh_addr = strdup (buf);
  495.     dlp -> dlh_time = utc;
  496.     dlp -> dlh_dn = NULLCP;
  497.     dlp -> dlh_next = Qstruct.dl_expansion_history;
  498.     Qstruct.dl_expansion_history = dlp;
  499. }    
  500.  
  501. static void hdr_conversion (str)
  502. char    *str;
  503. {    
  504.     (void) compress (str, str);
  505.     if (lexequ (str, "prohibited") == 0)
  506.         Qstruct.implicit_conversion_prohibited = 1;
  507. }
  508.  
  509. static void hdr_convert_with_loss (str)
  510. char    *str;
  511. {    
  512.     (void) compress (str, str);
  513.     if (lexequ (str, "prohibited") == 0)
  514.         Qstruct.conversion_with_loss_prohibited = 1;
  515. }
  516.  
  517. static void hdr_x400_received (str)
  518. char    *str;
  519. {
  520.     Trace    *trace;
  521.  
  522.     PP_DBG (("submit/hdr_x400_received (%s)", str));
  523.  
  524.     trace_count++;
  525.  
  526.     if (ch_inbound -> ch_access == CH_MTS)
  527.         err_abrt (RP_MECH,
  528.               "No trace information allowed for local submission");
  529.  
  530.     x400_receiveds++;
  531.  
  532.     if (date_trace != (Trace *) NULL) {
  533.         /* remove date generated trace */
  534.         /* should never need as trace should be above */
  535.         /* date fields */
  536.         if (Qstruct.trace == date_trace)
  537.             Qstruct.trace = Qstruct.trace->trace_next;
  538.         else {
  539.             for (trace = Qstruct.trace;
  540.                  trace != (Trace *) NULL
  541.                  && trace->trace_next != date_trace;
  542.                  trace = trace->trace_next)
  543.                 continue;
  544.             if (trace->trace_next == date_trace)
  545.                 trace->trace_next = date_trace->trace_next;
  546.         }
  547.         date_trace->trace_next = (Trace *) NULL;
  548.         trace_free(date_trace);
  549.         date_trace = (Trace *) NULL;
  550.     }
  551.                 
  552.     trace = (Trace *) smalloc (sizeof(Trace));
  553.     bzero ((char *) trace, sizeof(*trace));
  554.  
  555.     if (rfc2x400trace (trace, str) == OK) {
  556.         PP_DBG (("rfc2x400trace OK"));
  557.         trace -> trace_next = Qstruct.trace;
  558.         Qstruct.trace = trace;
  559.     } else
  560.            free((char *) trace);
  561. }
  562.  
  563. static void hdr_def_deliv (str)
  564. char    *str;
  565. {
  566.     if (Qstruct.defertime != 0)
  567.         /* don't override */
  568.         return;
  569.     if (rfc2UTC (str, &Qstruct.defertime) != OK) 
  570.         /* ignore */
  571.         Qstruct.defertime = 0;
  572. }
  573.  
  574. static void hdr_latest_time (str)
  575. char    *str;
  576. {
  577.     if (Qstruct.latest_time != 0)
  578.         /* don't override */
  579.         return;
  580.     if (rfc2UTC (str, &Qstruct.latest_time) != OK)
  581.         Qstruct.latest_time = 0;
  582.     else
  583.         /* assume if present then critical */
  584.         Qstruct.latest_time_crit = Q_LATESTTIME;
  585. }
  586.  
  587. static void hdr_date (str)
  588. char    *str;
  589. {
  590.     Trace    *tp;
  591.     char    *adr = NULL;
  592.     OR_ptr    or;
  593.  
  594.     if (x400_receiveds > 0)
  595.         /* have x400-received lines */
  596.         /* so don't need to add date generated trace */
  597.         return;
  598.  
  599.     if (cor_date != NULLCP)
  600.         cor_date = strdup(str);
  601.  
  602.     tp = (Trace *) smalloc (sizeof (Trace));
  603.     bzero ((char *)tp, sizeof(*tp));
  604.     if (rfc2UTC (str, &(tp -> trace_DomSinfo.dsi_time)) != OK) {
  605.         PP_LOG(LLOG_EXCEPTIONS,
  606.                ("submit/hdr_date unable to convert time to UTC '%s'",
  607.             str));
  608.         free((char *) tp);
  609.         return;
  610.     }
  611.     tp->trace_DomSinfo.dsi_action = ACTION_RELAYED;
  612.     
  613.     if (Qstruct.Oaddress->ad_r400adr != NULL) {
  614.         adr = strdup(Qstruct.Oaddress->ad_r400adr);
  615.         if ((or = or_std2or(adr)) == NULLOR) {
  616.             PP_LOG(LLOG_EXCEPTIONS,
  617.                    ("submit/hdr_date unable to get OR tree for orig '%s'", Qstruct.Oaddress->ad_r400adr));
  618.             free((char *)adr);
  619.         }
  620.     } 
  621.     if (or == NULL && Qstruct.Oaddress->ad_r822adr != NULL) {
  622.         adr = strdup(Qstruct.Oaddress->ad_r822adr);
  623.         if (or_rfc2or_aux (adr, &or, 1) == NOTOK) {
  624.             PP_LOG(LLOG_EXCEPTIONS,
  625.                    ("submit/hdr_date unable to get OR tree for orig '%s'", Qstruct.Oaddress->ad_r822adr));
  626.             free ((char *) adr);
  627.         }
  628.     }
  629.  
  630.     if (or == NULL
  631.         ||     fillin_DomId (&tp -> trace_DomId, or, adr) == NOTOK) {
  632.         PP_LOG(LLOG_EXCEPTIONS,
  633.                ("submit/hdr_date unable to create gld for orig"));
  634.         free ((char *) tp);
  635.         return;
  636.     }
  637.     
  638.     or_free(or);
  639.     if (Qstruct.Oaddress->ad_r822adr != NULLCP) {
  640.         AP_ptr    tree, group,
  641.             name, local,
  642.             domain, route;
  643.         ap_s2p(Qstruct.Oaddress->ad_r822adr,
  644.                &tree, &group, &name,
  645.                &local, &domain, &route);
  646.         rfc822_norm_dmn (domain, ch_inbound->ch_ad_order);
  647.         tp -> trace_mta = strdup(domain -> ap_obvalue);
  648.         ap_sqdelete (tree, NULLAP);
  649.         ap_free(tree);
  650.     }
  651.     free(adr);
  652.     if (tp -> trace_DomSinfo.dsi_time == NULL)
  653.         tp -> trace_DomSinfo.dsi_time = utcnow ();
  654.     tp -> trace_next = Qstruct.trace;
  655.     date_trace = Qstruct.trace = tp;
  656. }
  657.  
  658. /* ARGSUSED */
  659. static void hdr_x400_mts_id (str)
  660. char    *str;
  661. {
  662.     if (Qstruct.msgid.mpduid_string != NULL)
  663.         MPDUid_free(&Qstruct.msgid);
  664.     /* force random generation to avoid clashes */
  665.     MPDUid_new(&Qstruct.msgid);
  666.     got_x400_mts_id = TRUE;
  667. #ifdef KEEPMTSID
  668.     rfc2msgid(&Qstruct.msgid, str);
  669. #endif
  670. }
  671.  
  672. static void hdr_orig_eit (str)
  673. char    *str;
  674. {
  675.     if (Qstruct.orig_encodedinfo.eit_types != NULL)
  676.         /* override */
  677.         encodedinfo_free (&Qstruct.orig_encodedinfo);
  678.     (void) rfc2encinfo (&Qstruct.orig_encodedinfo, str);
  679. }
  680.  
  681. static void hdr_msgid (str)
  682. char    *str;
  683. {
  684.     MPDUid    *mp;
  685.     char    *midstring, *cp;
  686.     AP_ptr    ap, local, domain;
  687.     OR_ptr    or;
  688.  
  689.     if (cor_mid == NULLCP)
  690.         cor_mid = strdup(str);
  691.  
  692.     if (got_x400_mts_id == TRUE)
  693.         return;
  694.  
  695.     if (Qstruct.msgid.mpduid_string == NULL)
  696.         MPDUid_new  (&Qstruct.msgid);
  697.  
  698.     mp = &Qstruct.msgid;
  699.     if (mp -> mpduid_string != NULLCP)
  700.         free (mp -> mpduid_string);
  701.     (void) compress (str, str);
  702.     if ((int) strlen(str) > UB_LOCAL_ID_LENGTH) {
  703.         char tbuf[UB_LOCAL_ID_LENGTH+1];
  704.         (void) strncpy (tbuf, str, UB_LOCAL_ID_LENGTH);
  705.         tbuf[UB_LOCAL_ID_LENGTH] = 0;
  706.         mp -> mpduid_string = strdup (tbuf);
  707.     }
  708.     else mp -> mpduid_string = strdup (str);
  709.  
  710.     if ((midstring = index (str, '<')) == NULLCP
  711.         || (cp = rindex(str, '>')) == NULLCP) 
  712.         return;
  713.     *cp ='\0';
  714.     midstring++;
  715.  
  716.     if (ap_s2p(midstring, &ap, NULLAPP, NULLAPP, &local,
  717.            &domain, NULLAPP) == (char *) NOTOK)
  718.         return;
  719.     if (domain != NULLAP) {
  720.         rfc822_norm_dmn (domain, 
  721.                  Qstruct.inbound->li_chan->ch_ad_order);
  722.         if (or_domain2or(domain->ap_obvalue, &or) != NOTOK) {
  723.             OR_ptr    c, admd, prmd;
  724.             
  725.             or_chk_admd(&or);
  726.             if ((c = or_find(or, OR_C, NULLCP)) != NULLOR
  727.                 && (admd = or_find(or, OR_ADMD, NULLCP)) != NULLOR
  728.                 && (prmd = or_find(or, OR_PRMD, NULLCP)) != NULLOR) {
  729.                 /* swap generated with found */
  730.                 if (mp->mpduid_DomId.global_Country)
  731.                     free(mp->mpduid_DomId.global_Country);
  732.                 mp->mpduid_DomId.global_Country = strdup(c->or_value);
  733.                 if (mp->mpduid_DomId.global_Admin)
  734.                     free(mp->mpduid_DomId.global_Admin);
  735.                 mp->mpduid_DomId.global_Admin = strdup(admd->or_value);
  736.                 if (mp->mpduid_DomId.global_Private)
  737.                     free(mp->mpduid_DomId.global_Private);
  738.                 mp->mpduid_DomId.global_Private = strdup(prmd->or_value);
  739.             }
  740.             if (or)
  741.                 or_free(or);
  742.         }
  743.     }
  744.     
  745.     ap_sqdelete(ap, NULLAP);
  746. }    
  747.  
  748.  
  749. /* -- take comments from 'from' & add to 'to' leaving 'from' without any -- */
  750.  
  751. static void hdr_remcomm (from, to)
  752. char        *from;
  753. char        *to;
  754. {
  755.     char    *start = from,
  756.         *r = to,
  757.         *s,
  758.         *p,
  759.         *q;
  760.  
  761.  
  762.     if (start) {
  763.  
  764.         /* -- in case of NULL start ie missing date -- */
  765.  
  766.         PP_DBG (("submit/hdr_remcomm (%s,%s)", from, to));
  767.  
  768.         /* -- get to end -- */
  769.         while (*r != '\0')
  770.             r++;
  771.  
  772.         for (p = start ; (p = index (p, '(')) != NULLCP;) {
  773.             if ((q = index (p, ')')) == NULLCP) {
  774.                 *p = '\0';
  775.                 break;
  776.             }
  777.  
  778.             if (*to != '\0')
  779.                 *r++ = ' ';
  780.  
  781.             for (s = p; s <= q; *r++ = *s++) continue;
  782.  
  783.             (void) strcpy (p, q+1);
  784.  
  785.         }    /* -- for -- */
  786.  
  787.         *r = '\0';
  788.         (void) compress (from, from);
  789.     }  /* -- if -- */
  790.     else
  791.         PP_DBG (("submit/hdr_remcomm (NULL, %s)",to));
  792. }
  793.  
  794. static void hdr_via (contents)
  795. char    *contents;
  796. {
  797.     register Trace        *tp;
  798.     char    *datestart = NULLCP,
  799.         *argv[25], *domain, extraspace[LINESIZE];
  800.     OR_ptr    or;
  801.  
  802.     PP_DBG (("submit/hdr_via (%s)", contents));
  803.  
  804.     trace_count++;
  805.     
  806.     if (trace_count == 1)
  807.         return;/* we've added the first trace! */
  808.     
  809.     if (ch_inbound -> ch_access == CH_MTS)
  810.         err_abrt (RP_MECH,
  811.               "No trace information allowed for local submission");
  812.  
  813.     /* -- rip out the comments -- */
  814.  
  815.     *extraspace = '\0';
  816.     hdr_remcomm (contents, extraspace);
  817.  
  818.     if ((datestart = index (contents, ';')) != NULLCP)
  819.         *datestart++ = '\0';
  820.  
  821.     if (sstr2arg (contents, 25, argv, ",\t ") < 1 
  822.         || argv[0] == NULLCP)
  823.         return;
  824.  
  825.     domain = strdup(argv[0]);
  826.     or = NULLOR;
  827.     if (or_domain2or (domain, &or) == NOTOK) {
  828.         PP_TRACE(("unable to parse domain '%s' to OR tree", argv[0]));
  829.         return;
  830.     }
  831.     or_chk_admd (&or);
  832.     tp = (Trace *) smalloc (sizeof (Trace));
  833.     bzero ((char *)tp, sizeof(*tp));
  834.     
  835.     if (fillin_DomId (&tp -> trace_DomId, or, argv[0]) == NOTOK){
  836.         free ((char *) tp);
  837.         return;
  838.     }
  839.  
  840.     or_free(or);
  841.     free(domain);
  842.     tp -> trace_mta = strdup(argv[0]);
  843.  
  844.     if (datestart == NULLCP || 
  845.         rfc2UTC(datestart,&(tp->trace_DomSinfo.dsi_time)) == NOTOK)
  846.         tp -> trace_DomSinfo.dsi_time = utcnow();
  847.  
  848.     tp->trace_DomSinfo.dsi_action = ACTION_RELAYED;
  849.     tp -> trace_next = Qstruct.trace;
  850.     Qstruct.trace = tp;
  851. }
  852.  
  853.  
  854.     
  855.     
  856. static void hdr_rcv (contents)
  857. char    *contents;
  858. {
  859.     register Trace        *tp;
  860.     char    *bystart = NULLCP, *datestart = NULLCP,
  861.         *argv[25], *domain, extraspace[LINESIZE];
  862.     int    argc, i;
  863.     OR_ptr    or;
  864.  
  865.     PP_DBG (("submit/hdr_rcv (%s)", contents));
  866.  
  867.     trace_count++;
  868.     
  869.     if (trace_count == 1)
  870.         return;/* we've added the first trace! */
  871.     
  872.     if (ch_inbound -> ch_access == CH_MTS)
  873.         err_abrt (RP_MECH,
  874.               "No trace information allowed for local submission");
  875.     /* -- rip out the comments -- */
  876.  
  877.     *extraspace = '\0';
  878.     hdr_remcomm (contents, extraspace);
  879.  
  880.     if ((datestart = index (contents, ';')) != NULLCP)
  881.         *datestart++ = '\0';
  882.     
  883.     argc = sstr2arg (contents, 25, argv, ",\t ");
  884.     
  885.     for (i = 0; i < argc; i++) {
  886.         if (lexequ (argv [i], "by") == 0) {
  887.             if (bystart == NULLCP && i < argc -1) {
  888.                 bystart = argv [++i];
  889.                 continue;
  890.             }
  891.         }
  892.     }
  893.     
  894.     if (bystart == NULLCP)
  895.         return;
  896.     domain = strdup(bystart);
  897.     or = NULLOR;
  898.     if (or_domain2or (domain, &or) == NOTOK) {
  899.         PP_TRACE(("unable to parse domain '%s' to OR tree", bystart));
  900.         return;
  901.     }
  902.     or_chk_admd (&or);
  903.  
  904.     tp = (Trace *) smalloc (sizeof (Trace));
  905.     bzero ((char *)tp, sizeof(*tp));
  906.     
  907.     if (fillin_DomId (&tp -> trace_DomId, or, bystart) == NOTOK){
  908.         free ((char *) tp);
  909.         return;
  910.     }
  911.  
  912.     or_free(or);
  913.     free(domain);
  914.     tp -> trace_mta = strdup(bystart);
  915.  
  916.     if (datestart == NULLCP || 
  917.         rfc2UTC(datestart,&(tp->trace_DomSinfo.dsi_time)) == NOTOK)
  918.         tp -> trace_DomSinfo.dsi_time = utcnow();
  919.  
  920.     tp->trace_DomSinfo.dsi_action = ACTION_RELAYED;
  921.     tp -> trace_next = Qstruct.trace;
  922.     Qstruct.trace = tp;
  923. }
  924.         
  925.  
  926.  
  927. static int getline (bp, fp)
  928. char    **bp;
  929. FILE    *fp;
  930. {
  931.     static char *buf;
  932.     static int bufsiz = 0;
  933.     int    count;
  934.     char    *cp;
  935.     int    c;
  936.  
  937.     if (buf == NULLCP)
  938.         buf = smalloc (bufsiz = BUFSIZ);
  939.     for (cp = buf, count = 0; ; count ++) {
  940.         if (count >= bufsiz - 5) {
  941.             int curlen = cp - buf;
  942.             buf = realloc (buf, (unsigned) (bufsiz += BUFSIZ));
  943.             if (buf == NULL)
  944.                 err_abrt (RP_LIO, "Out of memeory");
  945.             cp = buf + curlen;
  946.         }
  947.         switch (c = getc (fp)) {
  948.             case '\n':
  949.             *cp ++ = ' ';
  950.             if ((c = getc(fp)) == ' ' || c == '\t')
  951.                 continue;
  952.             ungetc (c, fp);
  953.             break;
  954.             case EOF:
  955.             if (cp == buf)
  956.                 return NOTOK;
  957.             break;
  958.             default:
  959.             *cp ++ = c;
  960.             continue;
  961.         }
  962.         break;
  963.     }
  964.     *cp = '\0';
  965.     *bp = buf;
  966.     return OK;
  967. }
  968.  
  969. static int fillin_DomId (domId, or, str)
  970. GlobalDomId    *domId;
  971. OR_ptr        or;
  972. char        *str;
  973. {
  974.     OR_ptr    tmp_or;
  975.  
  976.     if ((tmp_or = or_find (or, OR_C, NULLCP)) == NULLOR) {
  977.         PP_LOG(LLOG_EXCEPTIONS,
  978.                ("submit/fillin_DomId: no country in '%s'", str));
  979.         return NOTOK;
  980.     }
  981.     domId->global_Country = strdup(tmp_or -> or_value);
  982.     
  983.     if ((tmp_or = or_find (or, OR_ADMD, NULLCP)) == NULLOR) {
  984.         PP_LOG(LLOG_EXCEPTIONS,
  985.                ("submit/fillin_DomId: no ADMD in '%s'", str));
  986.         free ((char *) domId -> global_Country);
  987.         return NOTOK;
  988.     }
  989.     domId->global_Admin = strdup(tmp_or -> or_value);
  990.     
  991.     if ((tmp_or = or_find (or, OR_PRMD, NULLCP)) != NULLOR) 
  992.         domId->global_Private = strdup(tmp_or -> or_value);
  993.     return OK;
  994. }
  995.  
  996. static int add_str (buf, s1, s2, len)
  997. char    buf[];
  998. char    *s1, *s2;
  999. int len;
  1000. {
  1001.     int l1, l2;
  1002.     if (len <= 0)
  1003.         return len;
  1004.     l1 = strlen(s1);
  1005.     l2 = strlen(s2);
  1006.     if (l1 + 2>= len) return len;
  1007.     if (buf[0]) {
  1008.         (void) strcat(buf, ",\n");
  1009.         len -= 2;
  1010.     }
  1011.     (void) strcat (buf, s1);
  1012.     len -= l1;
  1013.     if (len > l2) {
  1014.         (void) strcat (buf, s2);
  1015.         len -= l2;
  1016.     }
  1017.     else {
  1018.         (void) strncat (buf, s2, len - 1);
  1019.         len = 0;
  1020.     }
  1021.     return len;
  1022. }
  1023.  
  1024. static void do_correlators()
  1025. {
  1026.     char    buf[2*BUFSIZ], realbuf[BUFSIZ+1];
  1027.     PS    ps;
  1028.     PE    pe;
  1029.     int    len;
  1030.     char    *cp;
  1031.  
  1032.     buf[0] = '\0';
  1033.     len = 512;
  1034.     buf[len] = 0;
  1035.     if (NULLCP != cor_subject) {
  1036.         len = add_str (buf, "Subject: ", cor_subject, len);
  1037.         free(cor_subject);
  1038.         cor_subject = NULLCP;
  1039.     }
  1040.  
  1041.     if (NULLCP != cor_mid) {
  1042.         len = add_str (buf, "Message-ID: ", cor_mid, len);
  1043.         free(cor_mid);
  1044.         cor_mid = NULLCP;
  1045.     }
  1046.  
  1047.     if (NULLCP != cor_date) {
  1048.         len = add_str (buf, "Date: ", cor_date, len);
  1049.         free(cor_date);
  1050.         cor_date = NULLCP;
  1051.     }
  1052.  
  1053.     if ('\0' != cor_to) {
  1054.         len = add_str (buf, "To: ", cor_to, len);
  1055.         cor_to[0] = '\0';
  1056.     }
  1057.  
  1058.     realbuf[0] = '\0';
  1059.     if ((int) strlen(buf) >= ub_content_correlator_length) {
  1060.         (void) strncat (realbuf, buf,
  1061.                 (ub_content_correlator_length-strlen("...")));
  1062.         (void) strcat (realbuf, "...");
  1063.     } else
  1064.         (void) strcat (realbuf, buf);
  1065.     
  1066.     Qstruct.pp_content_correlator = strdup(realbuf);
  1067.  
  1068.     pe = oct2prim(realbuf, strlen(realbuf));
  1069.  
  1070.     if ((ps = ps_alloc (str_open)) == NULLPS) {
  1071.         PP_LOG (LLOG_EXCEPTIONS, ("Can't allocate PS"));
  1072.         return;
  1073.     }
  1074.  
  1075.     len = ps_get_abs (pe);
  1076.     cp = smalloc (len);
  1077.  
  1078.     if (str_setup (ps, cp, len, 1) == NOTOK) {
  1079.         PP_LOG (LLOG_EXCEPTIONS, ("Can't setup stream [%s]",
  1080.                       ps_error (ps -> ps_errno)));
  1081.         return;
  1082.     }
  1083.  
  1084.     if (pe2ps (ps, pe) == NOTOK) {
  1085.         PP_LOG (LLOG_EXCEPTIONS,
  1086.             ("pe2ps failed [%s]", ps_error (ps -> ps_errno)));
  1087.         return;
  1088.     }
  1089.     
  1090.     ps_free (ps);
  1091.  
  1092.     if ((Qstruct.general_content_correlator = str2qb (cp, len, 1)) == NULL)
  1093.         return;
  1094.     
  1095.     free(cp);
  1096.     pe_free(pe);
  1097. }
  1098.  
  1099. static void hdr_prohibition(str, pchar)
  1100. char    *str, *pchar;
  1101. {
  1102.     compress(str, str);
  1103.     if (lexequ(str, "allowed") == 0)
  1104.         *pchar = TRUE;
  1105.     else if (lexequ(str, "prohibited") == 0)
  1106.         *pchar = FALSE;
  1107.     else
  1108.         PP_NOTICE(("Unknown string encoding for prohibition: '%s'",
  1109.                str));
  1110. }
  1111.  
  1112. static void hdr_gen_del_report ()
  1113. {
  1114.     ADDR    *ix;
  1115.  
  1116.     for (ix = Qstruct.Raddress;
  1117.          ix != NULLADDR;
  1118.          ix = ix -> ad_next) {
  1119.         if (ix -> ad_resp == TRUE) 
  1120.             /* set for +ve drs */
  1121.             ix -> ad_usrreq = AD_USR_CONFIRM;
  1122.     }
  1123. }
  1124.  
  1125. static void hdr_prev_non_del_report ()
  1126. {
  1127.     ADDR    *ix;
  1128.  
  1129.     for (ix = Qstruct.Raddress;
  1130.          ix != NULLADDR;
  1131.          ix = ix -> ad_next) {
  1132.         if (ix -> ad_resp == TRUE)
  1133.             /* no drs at all */
  1134.             ix -> ad_usrreq = AD_USR_NOREPORT;
  1135.     }
  1136. }
  1137.